#include<bits/stdc++.h>
using namespace std;
int T,n,m,l,v;
const int N=1e5+8;
struct node{
    double v,a,d;
}car[N];
struct node_line{
    double l,r;
    bool lcc,rcc;
}xd[N];
int tp;
double she[N];//detect id; 
unordered_map <int,int>ump,ump2;
bool cmp(node_line a,node_line b){
    if(a.l>b.l) return true;
    return false;
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    scanf("%d",&T);
    for(int qustion=1;qustion<=T;qustion++){
        ump.clear();
        tp=0;
        scanf("%d %d %d %d",&n,&m,&l,&v);//carnum cenum len max_speed
        for(int i=1;i<=n;i++){
            scanf("%lf %lf %lf",&car[i].d,&car[i].v,&car[i].a);//zuobiao,v0,a
        }
        for(int i=1;i<=m;i++){
            scanf("%lf",&she[i]);//dec id
            ump[int(she[i])]=1;//mark
        }
        for(int i=N*10-10;i>=1;i--){
            
            if(ump[i]==1) ump2[i]=i;
            else ump2[i]=ump2[i+1];
        }
        for(int i=1;i<=N*10;i++){
            ump[i]+=ump[i-1];
        }
        sort(she+1,she+m+1);

        for(int i=1;i<=n;i++){
            double v0=car[i].v,x0=car[i].d,a=car[i].a,xs,xt;
            bool css,cst;
            if(v0<v && a<=0) continue;//never
            double dx;
            if(a>0){
                dx=(v*v-v0*v0)/2/a;
                if(dx<0) xt=l,css=true,cst=true;
                else if(dx==0) xt=l,css=false,cst=true;
                else{
                    xs=x0+dx;
                    if(xs>=l) continue;//never
                    css=false,cst=true;
                    xt=l;
                }
            }
            else if(a==0){
                if(v0>v){
                    css=true;
                    cst=true;
                    xs=x0,xt=l;
                }
                else continue;//never
            }
            else{
                dx=(v*v-v0*v0)/2/a;
                if(dx<0) continue;//never
                xt=dx+x0,cst=false;
                xs=x0,css=true;
            }
            // printf("%d:",i);
            // if(css==true) printf("[");
            // else printf("(");
            // printf("%lf,%lf",xs,xt);
            // if(cst==true) printf("]");
            // else printf(")");
            // puts("");


            if((css==true && ump[xs]==1) ||(cst==true && ump[xt]==1)){
                tp++,xd[tp].lcc=css,xd[tp].rcc=cst,xd[tp].l=xs,xd[tp].r=xt;//get into stack
            }
            else{
                int can_th_st=-1,can_th_ed=-1;
                if(css==false && xs==floor(xs)) can_th_st=xs+1;
                if(cst==false && xt==floor(xt)) can_th_ed=xt-1;
                //simple solve down
                if(can_th_ed==-1) can_th_ed=floor(xt);
                if(can_th_st==-1) can_th_st=ceil(xs);
                //solve down
                if(ump[can_th_ed]-ump[can_th_st-1]!=0){
                    tp++,xd[tp].lcc=css,xd[tp].rcc=cst,xd[tp].l=xs,xd[tp].r=xt;//get into stack
                }
            }
        }
        printf("%d ",tp);//right
        for(int i=1;i<=tp;i++){
            bool solvel=false,solver=false;
            if(xd[i].lcc==true && xd[i].l==ceil(xd[i].l)) solvel=true;
            if(xd[i].rcc==true && xd[i].r==ceil(xd[i].r)) solver=true;
            if(solvel==false) xd[i].l=ceil(xd[i].l);
            if(solver==false) xd[i].r=floor(xd[i].r);
        }
        sort(xd+1,xd+tp+1,cmp);
        int used=0;//used
        for(int i=1;i<=n;i++){
            int nc=ump2[xd[i].l];//we choose this
            used++;
            while(nc<=xd[i].r && i<=n) i++;
        }
        printf("%d\n",m-used);

    }
    return 0;
}